using System;
using System.Collections;
using System.Collections.Generic;
using NHibernate;
using NHibernate.Criterion;
using SGP.Common;
using SGP.IDAL;
using SGP.Nhibernate.Model;

namespace SGP.NhibernateDAL
{
    /// <summary>
    /// Classe de operacoes com o banco de dados
    /// </summary>
    public class PatrimonioDAL : IPatrimonioDAL
    {
        #region CRUD Methods

        /// <summary>
        /// Carrega o objeto atraves do id
        /// </summary>
        /// <param name="idPatrimonio"></param>
        /// <returns></returns>
        public Patrimonio Load(int idPatrimonio)
        {
            ISession session = NhibernateHelper.GetCurrentSession();
            //ITransaction transaction = session.BeginTransaction();

            Patrimonio patrimonio = (Patrimonio)session.Load(typeof(Patrimonio), idPatrimonio);

            return patrimonio;
        }

        /// <summary>
        /// Retorna todos os patrimonios cadastrados
        /// </summary>
        /// <returns>Lista de Patrimonios</returns>
        public IList<Patrimonio> FindAll()
        {
            ISession session = NhibernateHelper.GetCurrentSession();
            //ITransaction transaction = session.BeginTransaction();

            ICriteria criteria = session.CreateCriteria(typeof(Patrimonio));

            return this.ConvertToGenericList(criteria.List());
        }

        /// <summary>
        /// Retorna todos os patrimonios de uma pessoa
        /// </summary>
        /// <param name="idPessoa"></param>
        /// <returns></returns>
        public IList<Patrimonio> FindByPessoa(int idPessoa)
        {
            ISession session = NhibernateHelper.GetCurrentSession();
            Pessoa pessoa = new Pessoa();

            pessoa = (Pessoa)session.Load(typeof(Pessoa), idPessoa);

            return pessoa.Patrimonios;
        }
        /// <summary>
        /// Procura pelo nome do patrimonio
        /// </summary>
        /// <param name="nomePatrimonio"></param>
        /// <returns></returns>
        public IList<Patrimonio> FindByNome(string nomePatrimonio)
        {
            ISession session = NhibernateHelper.GetCurrentSession();

            ICriteria criteria = session.CreateCriteria(typeof(Patrimonio));
            criteria.Add(Expression.Like("PatNmPatrimonio", "%" + nomePatrimonio + "%"));

            return this.ConvertToGenericList(criteria.List());
        }

        public IList<Patrimonio> FindByQuantidade(int quantidade)
        {
            ISession session = NhibernateHelper.GetCurrentSession();

            ICriteria criteria = session.CreateCriteria(typeof(Patrimonio));
            criteria.Add(Expression.Eq("PatQtQuantidade", quantidade));

            return this.ConvertToGenericList(criteria.List());
        }

        public IList<Patrimonio> FindByCor(string cor)
        {
            ISession session = NhibernateHelper.GetCurrentSession();
            IQuery query =
                session.CreateQuery("select p.Patrimonio from PatrimonioDet as p where " +
                                    "p.PdtNmCor like :cor");
            query.SetString("cor", '%' + cor + '%');

            return this.ConvertToGenericList(query.List());
        }

        public IList<Patrimonio> FindByLargura(decimal largura)
        {
            ISession session = NhibernateHelper.GetCurrentSession();

            IQuery query =
                 session.CreateQuery("select p.Patrimonio from PatrimonioDet as p where " +
                                     "p.PdtLargura = :largura");
            query.SetDecimal("largura", largura);

            return this.ConvertToGenericList(query.List());
        }

        public IList<Patrimonio> FindByAltura(decimal altura)
        {
            ISession session = NhibernateHelper.GetCurrentSession();

            IQuery query =
                session.CreateQuery("select p.Patrimonio from PatrimonioDet as p where " +
                                    "p.PdtAltura = :altura");
            query.SetDecimal("altura", altura);

            return this.ConvertToGenericList(query.List());
        }

        public IList<Patrimonio> FindByProfundidade(decimal profundidade)
        {
            ISession session = NhibernateHelper.GetCurrentSession();

            IQuery query =
                session.CreateQuery("select p.Patrimonio from PatrimonioDet as p where " +
                                    "p.PdtProfundidade = :profundidade");
            query.SetDecimal("profundidade", profundidade);

            return this.ConvertToGenericList(query.List());
        }

        public IList<Patrimonio> FindByPeso(decimal peso)
        {
            ISession session = NhibernateHelper.GetCurrentSession();
            IQuery query =
                           session.CreateQuery("select p.Patrimonio from PatrimonioDet as p where " +
                                               "p.PdtPeso = :peso");
            query.SetDecimal("peso", peso);

            return this.ConvertToGenericList(query.List());
        }

        public IList<Patrimonio> FindByPrecoCompra(decimal precoCompra)
        {
            ISession session = NhibernateHelper.GetCurrentSession();

            IQuery query =
                session.CreateQuery("select p.Patrimonio from PatrimonioDet as p where " +
                                                 "p.PdtPrecoCompra = :precoCompra");
            query.SetDecimal("precoCompra", precoCompra);

            return this.ConvertToGenericList(query.List());
        }

        public IList<Patrimonio> FindByPrecoVenda(decimal precoVenda)
        {
            ISession session = NhibernateHelper.GetCurrentSession();
            IQuery query =
                session.CreateQuery("select p.Patrimonio from PatrimonioDet as p where " +
                                                           "p.PdtPrecoVenda = :precoCompra");
            query.SetDecimal("precoVenda", precoVenda);

            return this.ConvertToGenericList(query.List());
        }

        /// <summary>
        /// Procura pelo preco atual de mercado do patrimonio
        /// </summary>
        /// <param name="precoAtual"></param>
        /// <returns></returns>
        public IList<Patrimonio> FindByPrecoAtual(decimal precoAtual)
        {
            ISession session = NhibernateHelper.GetCurrentSession();

            IQuery query =
                session.CreateQuery("select p.Patrimonio from PatrimonioDet as p where " +
                "p.PdtPrecoAtual= :precoAtual");
            query.SetDecimal("precoAtual", precoAtual);

            return this.ConvertToGenericList(query.List());
        }

        /// <summary>
        /// Procura pela data de aquisicao
        /// </summary>
        /// <param name="dataAquisicao"></param>
        /// <returns></returns>
        public IList<Patrimonio> FindByDataAquisicao(DateTime dataAquisicao)
        {
            ISession session = NhibernateHelper.GetCurrentSession();

            IQuery query =
                session.CreateQuery("select p.Patrimonio from PatrimonioDet as p where " +
                "p.PdtDtAquisicao = :dataAquisicao");
            query.SetDateTime("dataAquisicao", dataAquisicao);

            return this.ConvertToGenericList(query.List());
        }

        /// <summary>
        /// Procura pelo tipo do patrimonio
        /// </summary>
        /// <param name="dsTipo"></param>
        /// <returns></returns>
        public IList<Patrimonio> FindByTipo(string dsTipo)
        {
            ISession session = NhibernateHelper.GetCurrentSession();

            IQuery query =
                session.CreateQuery("select p.Patrimonio from PatrimonioDet as p where " +
                "p.PdtDsTipo = :tipo");
            
            query.SetString("tipo", '%' + dsTipo +'%');

            return this.ConvertToGenericList(query.List());
        }

        
        /// <summary>
        /// Insere um patrimonio no banco
        /// </summary>
        /// <param name="patrimonio"></param>
        public void Insert(Patrimonio patrimonio)
        {
            ISession session = NhibernateHelper.GetCurrentSession();
            ITransaction transaction = session.BeginTransaction();

            try
            {
                session.Save(patrimonio);
                transaction.Commit();
            }
            catch (Exception ex)
            {
                throw new HibernateException("Erro ao inserir o objeto no banco: " +
                ex.Message);
            }
            
        }

        /// <summary>
        /// Atualiza um patrimonio do banco de dados
        /// </summary>
        /// <param name="patrimonio"></param>
        public void Update(Patrimonio patrimonio)
        {
            ISession session = NhibernateHelper.GetCurrentSession();
            ITransaction transaction = session.BeginTransaction();

            try
            {
                session.Update(patrimonio);
                transaction.Commit();
            }
            catch (Exception ex)
            {
                throw new HibernateException("Erro ao atualizar o objeto no banco: " +
                ex.Message);
            }
        }

        /// <summary>
        /// Remove o patrimonio do banco de dados
        /// </summary>
        /// <param name="idPatrimonio"></param>
        public void Delete(Patrimonio patrimonio)
        {

            ISession session = NhibernateHelper.GetCurrentSession();
            ITransaction transaction = session.BeginTransaction();

            try
            {
                session.Delete(patrimonio);
                transaction.Commit();
            }
            catch (Exception ex)
            {
                throw new HibernateException("Erro ao excluir o objeto: " +
                ex.Message);
            }
        }

        #endregion

        #region Private Methods
        private IList<Patrimonio> ConvertToGenericList(IList patrimonios)
        {
            IList<Patrimonio> patrimoniosList = new List<Patrimonio>();

            foreach (Patrimonio patrimonio in patrimonios)
            {
                patrimoniosList.Add(patrimonio);
            }

            return patrimoniosList;
        }
        #endregion

    }
}